package reg.data;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import reg.domain.Asistencia;
import reg.domain.Manifestacion;
import reg.domain.Usuario;

public class JDBCUsuarioDAO implements IUsuarioDAO {

	private List<Usuario> allUsers = null;

	
	
	public List<Usuario> seleccionaTodosUsuarios() {
		if (allUsers == null) {
			Connection conn = ConnectionManager.getInstance().checkOut();
			PreparedStatement stmt = null;
			List<Usuario> searchResults = new LinkedList<Usuario>();
			ResultSet result = null;

			try {
				String sql = "SELECT * FROM Usuarios";
				stmt = conn.prepareStatement(sql);
				stmt.executeQuery();
				result = stmt.executeQuery();

				while (result.next()) {
					// TODO Tenemos que capturar los amigos con otra
					// consulta!!!!!!
					Usuario usuario = new Usuario();
					usuario.setNombre(result.getString("nombre"));
					usuario.setContrasenya(result.getString("contrasenya"));
					usuario.setDescripcion(result.getString("descripcion"));
					usuario.setFechaRegistro(result.getDate("fechaRegistro"));
					usuario.setEdad(result.getInt("edad"));
					usuario.setPrivilegios(result.getBoolean("privilegios"));
					usuario.setUltimoLogin(result.getDate("ultimoLogin"));
					usuario.setCiudad(result.getString("ciudad"));

					// /////////////////////////////////////////////////////////////////7
					// IConsulta para obtener los amigos

					PreparedStatement stmt4amigos = null;
					List<Usuario> searchResultsAmigos = new LinkedList<Usuario>();
					ResultSet resultAmigos = null;

					try {
						String sqlAmigos = "SELECT * FROM Usuarios WHERE idUsuario IN ( SELECT idAmigo FROM ( SELECT idUsuario, idAmigo FROM Usuarios NATURAL JOIN Amigos ) AS T WHERE idUsuario =  '"	+ result.getString("idUsuario") + "')";
						stmt4amigos = conn.prepareStatement(sqlAmigos);
						stmt4amigos.executeQuery();
						resultAmigos = stmt4amigos.executeQuery();

						while (resultAmigos.next()) {
							// TODO Tenemos que capturar los amigos con otra
							// consulta!!!!!!
							Usuario amigo = new Usuario();
							amigo.setNombre(resultAmigos.getString("nombre"));
							amigo.setContrasenya(resultAmigos.getString("contrasenya"));
							amigo.setDescripcion(resultAmigos.getString("descripcion"));
							amigo.setFechaRegistro(resultAmigos.getDate("fechaRegistro"));
							amigo.setEdad(resultAmigos.getInt("edad"));
							amigo.setPrivilegios(resultAmigos.getBoolean("privilegios"));
							amigo.setUltimoLogin(resultAmigos.getDate("ultimoLogin"));
							amigo.setCiudad(resultAmigos.getString("ciudad"));

							searchResultsAmigos.add(amigo);
						}
						
					} catch (SQLException e) {
						System.out.println("Message: " + e.getMessage());
						System.out.println("SQLState: " + e.getSQLState());
						System.out.println("ErrorCode: " + e.getErrorCode());
					} finally {
						try {
							if (resultAmigos != null)
								resultAmigos.close();
							if (stmt4amigos != null)
								stmt4amigos.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}

					// //////////////////////////////////////////////////////////////////////////////
					// Consultar para obtener las manifestaciones

					PreparedStatement stmt4manifestaciones = null;
					List<Asistencia> searchResultsmanifestaciones = new LinkedList<Asistencia>();
					ResultSet resultManifestaciones = null;

					try {

						String sqlManifestaciones = "SELECT M.idManifestacion,M.nombre,M.descripcion,M.ciudad, M.organizadores,M.fecha,B.estado FROM Manifestacion AS M,Asistencia AS B WHERE idUsuario = '"
								+ result.getString("idUsuario")
								+ "' AND M.idManifestacion=B.idManifestacion AND B.idManifestacion IN( SELECT idManifestacion FROM Usuarios AS U, Asistencia AS A WHERE U.idUsuario = A.idUsuario )";
						stmt4manifestaciones = conn.prepareStatement(sqlManifestaciones);
						stmt4manifestaciones.executeQuery();
						resultManifestaciones = stmt4manifestaciones.executeQuery();

						while (resultManifestaciones.next()) {
							Manifestacion manifestacion = new Manifestacion();
							Asistencia asistencia = new Asistencia();
							manifestacion.setNombre(resultManifestaciones.getString("nombre"));
							manifestacion.setOrganizadores(resultManifestaciones.getString("organizadores"));
							manifestacion.setDescripcion(resultManifestaciones.getString("descripcion"));
							manifestacion.setFecha(resultManifestaciones.getDate("fecha"));
							manifestacion.setCiudad(resultManifestaciones.getString("ciudad"));
							asistencia.setEstado(resultManifestaciones.getBoolean("estado"));
							asistencia.setManifestacion(manifestacion);

							searchResultsmanifestaciones.add(asistencia);
						}
						
					} catch (SQLException e) {
						System.out.println("Message: " + e.getMessage());
						System.out.println("SQLState: " + e.getSQLState());
						System.out.println("ErrorCode: " + e.getErrorCode());
					} finally {
						try {
							if (resultManifestaciones != null)
								resultManifestaciones.close();
							if (stmt4manifestaciones != null)
								stmt4manifestaciones.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
					usuario.setAsistencias(searchResultsmanifestaciones);
					usuario.setAmigos(searchResultsAmigos);
					searchResults.add(usuario);
				}

			} catch (SQLException e) {
				System.out.println("Message: " + e.getMessage());
				System.out.println("SQLState: " + e.getSQLState());
				System.out.println("ErrorCode: " + e.getErrorCode());
			} finally {
				ConnectionManager.getInstance().checkIn(conn);
				try {
					if (result != null)
						result.close();
					if (stmt != null)
						stmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

			allUsers = searchResults;
			return searchResults;
		} else {
			return allUsers;
		}
	}

	
	
	public Usuario seleccionaUsuarioPorNombre(String nombre) {
		Connection conn = ConnectionManager.getInstance().checkOut();
		PreparedStatement stmt = null;
		Usuario usuario = new Usuario();
		ResultSet result = null;
		
		try {
			String sql = "SELECT * FROM Usuarios WHERE nombre='" + nombre + "'";
			stmt = conn.prepareStatement(sql);
			stmt.executeQuery();
			result = stmt.executeQuery();

			while (result.next()) {
				// TODO Tenemos que capturar los amigos con otra consulta!!!!!!
				usuario.setNombre(result.getString("nombre"));
				usuario.setContrasenya(result.getString("contrasenya"));
				usuario.setDescripcion(result.getString("descripcion"));
				usuario.setFechaRegistro(result.getDate("fechaRegistro"));
				usuario.setEdad(result.getInt("edad"));
				usuario.setPrivilegios(result.getBoolean("privilegios"));
				usuario.setUltimoLogin(result.getDate("ultimoLogin"));
				usuario.setCiudad(result.getString("ciudad"));

				// /////////////////////////////////////////////////////////////////7
				// IConsulta para obtener los amigos

				PreparedStatement stmt4amigos = null;
				List<Usuario> searchResultsAmigos = new LinkedList<Usuario>();
				ResultSet resultAmigos = null;

				try {
					String sqlAmigos = "SELECT * FROM Usuarios WHERE idUsuario IN ( SELECT idAmigo FROM ( SELECT idUsuario, idAmigo FROM Usuarios NATURAL JOIN Amigos ) AS T WHERE idUsuario =  '"
							+ result.getString("idUsuario") + "')";
					stmt4amigos = conn.prepareStatement(sqlAmigos);
					stmt4amigos.executeQuery();
					resultAmigos = stmt4amigos.executeQuery();

					while (resultAmigos.next()) {
						// TODO Tenemos que capturar los amigos con otra
						// consulta!!!!!!
						Usuario amigo = new Usuario();
						amigo.setNombre(resultAmigos.getString("nombre"));
						amigo.setContrasenya(resultAmigos.getString("contrasenya"));
						amigo.setDescripcion(resultAmigos.getString("descripcion"));
						amigo.setFechaRegistro(resultAmigos.getDate("fechaRegistro"));
						amigo.setEdad(resultAmigos.getInt("edad"));
						amigo.setPrivilegios(resultAmigos.getBoolean("privilegios"));
						amigo.setUltimoLogin(resultAmigos.getDate("ultimoLogin"));
						amigo.setCiudad(resultAmigos.getString("ciudad"));

						searchResultsAmigos.add(amigo);
					}
					
				} catch (SQLException e) {
					System.out.println("Message: " + e.getMessage());
					System.out.println("SQLState: " + e.getSQLState());
					System.out.println("ErrorCode: " + e.getErrorCode());
				} finally {
					try {
						if (resultAmigos != null)
							resultAmigos.close();
						if (stmt4amigos != null)
							stmt4amigos.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}

				// //////////////////////////////////////////////////////////////////////////////
				// Consultar para obtener las manifestaciones

				PreparedStatement stmt4manifestaciones = null;
				List<Asistencia> searchResultsmanifestaciones = new LinkedList<Asistencia>();
				ResultSet resultManifestaciones = null;

				try {
					String sqlManifestaciones = "SELECT M.idManifestacion,M.nombre,M.descripcion,M.ciudad, M.organizadores,M.fecha,B.estado FROM Manifestacion AS M,Asistencia AS B WHERE idUsuario = '"
							+ result.getString("idUsuario")
							+ "' AND M.idManifestacion=B.idManifestacion AND B.idManifestacion IN( SELECT idManifestacion FROM Usuarios AS U, Asistencia AS A WHERE U.idUsuario = A.idUsuario )";
					stmt4manifestaciones = conn.prepareStatement(sqlManifestaciones);
					stmt4manifestaciones.executeQuery();
					resultManifestaciones = stmt4manifestaciones.executeQuery();

					while (resultManifestaciones.next()) {
						Manifestacion manifestacion = new Manifestacion();
						Asistencia asistencia = new Asistencia();
						manifestacion.setNombre(resultManifestaciones.getString("nombre"));
						manifestacion.setOrganizadores(resultManifestaciones.getString("organizadores"));
						manifestacion.setDescripcion(resultManifestaciones.getString("descripcion"));
						manifestacion.setFecha(resultManifestaciones.getDate("fecha"));
						manifestacion.setCiudad(resultManifestaciones.getString("ciudad"));
						asistencia.setEstado(resultManifestaciones.getBoolean("estado"));
						asistencia.setManifestacion(manifestacion);

						searchResultsmanifestaciones.add(asistencia);
					}
					
				} catch (SQLException e) {
					System.out.println("Message: " + e.getMessage());
					System.out.println("SQLState: " + e.getSQLState());
					System.out.println("ErrorCode: " + e.getErrorCode());
				} finally {
					try {
						if (resultManifestaciones != null)
							resultManifestaciones.close();
						if (stmt4manifestaciones != null)
							stmt4manifestaciones.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
				
				usuario.setAsistencias(searchResultsmanifestaciones);
				usuario.setAmigos(searchResultsAmigos);

			}

		} catch (SQLException e) {
			System.out.println("Message: " + e.getMessage());
			System.out.println("SQLState: " + e.getSQLState());
			System.out.println("ErrorCode: " + e.getErrorCode());
		} finally {
			ConnectionManager.getInstance().checkIn(conn);
			try {
				if (result != null)
					result.close();
				if (stmt != null)
					stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return usuario;
	}



	@Override
	public void actualizaUltimoLogin(String usuario, Date fecha) {
		Connection conn = ConnectionManager.getInstance().checkOut();
		PreparedStatement stmt = null;
		ResultSet result = null;

		try {
			String sql = "UPDATE  Usuarios SET  ultimoLogin =  '"+fecha.toString()+"' WHERE  nombre='"+usuario+"'";
			stmt = conn.prepareStatement(sql);
			stmt.executeUpdate();
			
		} catch (SQLException e) {
			System.out.println("Message: " + e.getMessage());
			System.out.println("SQLState: " + e.getSQLState());
			System.out.println("ErrorCode: " + e.getErrorCode());
		} finally {
			ConnectionManager.getInstance().checkIn(conn);
			try {
				if (result != null)
					result.close();
				if (stmt != null)
					stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	
	public int obtenerIdUsuario(String nick){
		Connection conn = ConnectionManager.getInstance().checkOut();
		PreparedStatement stmt = null;
		Integer id = null;
		ResultSet result = null;
		
		try {
			String sql = "SELECT idUsuario FROM Usuarios WHERE nombre='" + nick + "'";
			stmt = conn.prepareStatement(sql);
			stmt.executeQuery();
			result = stmt.executeQuery();
			
			while (result.next()) {
				 id = result.getInt("idUsuario");
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return id;
	}



	@Override
	public Usuario getUsuarioSinAmigos(int idUsuario) {
		Connection conn = ConnectionManager.getInstance().checkOut();
		
		String sql = "SELECT * FROM Usuarios WHERE idUsuario = ?";
        PreparedStatement stmt = null;
        ResultSet result = null;
        
        Usuario user = new Usuario();

        try {
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, idUsuario);

            result = stmt.executeQuery();

            result.next();
            
            user.setIdUsuario(result.getInt("idUsuario"));
            user.setNombre(result.getString("nombre"));         
            user.setEdad(result.getInt("edad"));
            user.setPrivilegios(result.getBoolean("privilegios"));
            user.setFechaRegistro(result.getDate("fechaRegistro"));
            user.setDescripcion(result.getString("descripcion"));
            user.setCiudad(result.getString("ciudad"));
            user.setUltimoLogin(result.getDate("ultimoLogin"));
            
        } catch (SQLException e) {
            System.out.println("Message: " + e.getMessage());
            System.out.println("SQLState: " + e.getSQLState());
            System.out.println("ErrorCode: " + e.getErrorCode());
        } finally {
            try {
                if (result != null) {
                    result.close();
                }
                if (stmt != null) {
                    stmt.close();
                }
            } catch (SQLException e) {
            }
        }

        return user;
		
	}
}
